package com.android.myipc.biner;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;

import com.android.myipc.IBinderPool;

import java.util.concurrent.CountDownLatch;

/**
 * Created by Android Studio.
 * User: pengym
 * Date: 2020/11/16
 * Time: 15:03
 * Name: 作用类：
 */
public class BinderPool {
    private static final String TAG = "BinderPool";
    public static final int BINDER_NONE = -1;
    public static final int BINDER_COMPUTE = 0;
    public static final int BINDER_SECURITY_CENTER = 1;
    private Context context;
    private IBinderPool mBinderPool;
    private static volatile BinderPool sInstance;
    private CountDownLatch mConnectBinderPoolCountDownLath;

    public BinderPool(Context context) {
        this.context = context.getApplicationContext();
        connectBinderPoolService();
    }

    //单例模式-双重锁单例模式
    public static BinderPool getInstance(Context context) {
        if (sInstance == null) {
            synchronized (BinderPool.class) {
                if (sInstance == null) {
                    sInstance = new BinderPool(context);
                }
            }
        }
        return sInstance;
    }

    private synchronized void connectBinderPoolService() {
        mConnectBinderPoolCountDownLath = new CountDownLatch(1);
        Intent service = new Intent(context, BinderPoolService.class);
        context.bindService(service, mBinderPoolConnction, Context.BIND_AUTO_CREATE);
        try {
            mConnectBinderPoolCountDownLath.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public IBinder queryBinder(int binderCode) {
        IBinder binder = null;
        try {
            if (mBinderPool != null) {
                binder = mBinderPool.queryBinder(binderCode);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return binder;
    }

    private ServiceConnection mBinderPoolConnction = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinderPool = IBinderPool.Stub.asInterface(service);
            try {
                mBinderPool.asBinder().linkToDeath(mBinderPoolDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            mConnectBinderPoolCountDownLath.countDown();

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {


        }
    };

    private IBinder.DeathRecipient mBinderPoolDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            mBinderPool.asBinder().unlinkToDeath(mBinderPoolDeathRecipient,0);
            mBinderPool=null;
            connectBinderPoolService();
        }
    };
public static class BinderPoolImpl extends IBinderPool.Stub{

    public BinderPoolImpl(){
        super();
    }

    @Override
    public IBinder queryBinder(int binderCode) throws RemoteException {
        IBinder binder = null;
        switch (binderCode){
            case BINDER_SECURITY_CENTER:
//                binder=new SecurityCenterImpl();
                break;
            case BINDER_COMPUTE:
//                binder = new ComputeImpl();
                break;
            default:
                break;
        }
        return binder;
    }
}
}
